package com.mapbased.sfw.model;

import java.util.List;
import java.util.Map;

import org.dom4j.Element;
import org.dom4j.Node;

import com.mapbased.sfw.component.Headable;
import com.mapbased.sfw.component.XmlContext;

public class Page extends Fragment {

	protected String caption;
	private String masterPath;

	private int order;
	private FragmentBag masterPagebag;
	final private Map<String, RenderGroup> renderGroups = new java.util.HashMap<String, RenderGroup>();

	public String getCaption() {
		return caption;
	}

	public int getOrder() {
		return order;
	}

	@Override
	public void prepareHeadables(RenderContext rc) {
		super.prepareHeadables(rc);
		Fragment master = this.getMasterPage();
		while (master != null) {
			master.prepareHeadables(rc);
			master = ((Page) master).getMasterPage();
		}
	}

	@Override
	public void parseXml(Element ele, LoadContext lc) {
		String masterpath = lc.fetchAttribute(ele, "master");
		this.masterPath = masterpath;
		if (masterpath == null) {
			masterpath = Site.getMasterPath(path);
			// this.masterPagebag=lc.site.getMasterFragmentBag(path);
		} else if (masterpath.equalsIgnoreCase("null")
				|| masterpath.equalsIgnoreCase("none")) {
			masterpath = null;
		}
		this.masterPagebag = lc.site.getMasterFragmentBag(masterpath);

		this.caption = lc.fetchAttribute(ele, "caption");
		this.order = lc.fetchIntAttribute(ele, "order");

		List<Node> lns = ele.selectNodes("//*[@jid=\"$content$\"]");

		if (lns.size() == 0) {
			lc.parseElement(ele);
			String name = lc.fetchAttribute(ele, "name");
			if (name == null) {
				this.mainRenderGroup = lc.getRenderGroup();
			} else {
				this.renderGroups.put(name, lc.getRenderGroup());
			}

		} else {

			for (Node n : lns) {
				if (n instanceof Element) {
					Element e = (Element) n;

					String name = lc.fetchAttribute(e, "name");
					LoadContext clc = lc.createChild();
					clc.parseElementChildren(e);
					if (name == null) {
						this.mainRenderGroup = clc.getRenderGroup();
					} else {
						this.renderGroups.put(name, clc.getRenderGroup());
					}

				}
			}
		}

		this.components = lc.components;
		this.headables = lc.headables
				.toArray(new Headable[lc.headables.size()]);

	}

	public Fragment getMasterPage() {
		if (masterPagebag == null) {
			return null;
		}
		return masterPagebag.getFragment();
	}

	public RenderGroup getRenderGroup(String name) {
		if (name == null) {
			return this.mainRenderGroup;
		}
		return this.renderGroups.get(name);
	}

	public void render(RenderContext rc) {
		rc.setUrlPage(this);
		this.masterRender(rc);
	}

	protected void masterRender(RenderContext rc) {

		Page master = (Page) this.getMasterPage();
		if (master != null) {
			rc.currentMasterClient = this;
			master.masterRender(rc);
		} else {
			this.mainRenderGroup.render(rc);
		}

	}

	@Override
	public void toXml(XmlContext xc) {
		xc.srcPage = this;

		StringBuilder sb = xc.sb;
		sb.append("<div caption=\"").append(this.caption).append("\" order=\"")
				.append(this.order);
		if (this.masterPath != null)
			sb.append("\" master=\"").append(this.masterPath);
		sb.append("\" >\n");
		if (this.mainRenderGroup != null) {
			sb.append("<div jid=\"$content$\">\n");
			this.mainRenderGroup.toXml(xc);
			sb.append("</div>\n");
		}

		for (Map.Entry<String, RenderGroup> me : this.renderGroups.entrySet()) {

			sb.append("<div jid=\"$content$\" name=\"" + me.getKey() + "\">\n");
			me.getValue().toXml(xc);
			sb.append("</div>\n");
		}

		sb.append("</div>\n");

	}

	// private void masterToXml(XmlContext xc){
	//		
	// Page master = (Page) this.getMasterPage();
	// if (master != null) {
	// xc.currentClientPage = this;
	// master.masterToXml(xc);
	// } else {
	// StringBuilder sb=xc.sb;
	// sb.append("<div>\n");
	// if(this.mainRenderGroup!=null){
	// sb.append("<div jid=\"$content$\">\n");
	// this.mainRenderGroup.toXml(sb) ;
	// sb.append("</div>\n");
	// }
	//			
	// for(Map.Entry<String, RenderGroup> me:this.renderGroups.entrySet()){
	//				
	// sb.append("<div jid=\"$content$\" name=\""+me.getKey()+"\">\n");
	// me.getValue().toXml(sb) ;
	// sb.append("</div>\n");
	// }
	//			
	//			
	// sb.append("</div>\n");
	// }
	// }

	public long getLastModified() {
		return -1L;
	}

}
